package com.cfweb.api;

import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;

import javax.servlet.http.HttpSession;

import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import com.cfweb.controller.LoginHandler;
import com.cfweb.pojo.OauthToken;
import com.cfweb.util.CloudFoundryClientUtil;
import com.cfweb.util.MutiThreadUtil;
import com.cfweb.util.ResourceCall;
import com.cfweb.util.StringUtil;

public class BasicInfoApi {

	/**
	 * 通过orgName得到basicinfo，但只需要包含memoryUsed和memoryAll
	 * 
	 * @param resMap
	 * @param session
	 * @param orgName
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static void getMemoryServiceByOrgName(Map<String, Object> resMap, HttpSession session, String orgName)
			throws Exception {
		ThreadPoolExecutor executor = MutiThreadUtil.getExecutorService();
		HttpClient httpClient = new DefaultHttpClient();
		OauthToken token = (OauthToken) session.getAttribute(LoginHandler.TOKEN);
		String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
		// 得到所属orgName的所有spaces
		List<Map<String, Object>> list = SpaceApi.list_spaces_by_org(session, orgName);

		int memoryUsed = 0;
		int serviceNum = 0;
		// 遍历spaces
		for (Map<String, Object> map : list) {
			// 得到space的名字
			String space = (String) map.get("name");
			String spaceGuid = null;
			// 得到space的Guid
			if (!StringUtil.isEmpty(orgName) && !StringUtil.isEmpty(space)) {
				spaceGuid = UserApi.get_space_id(session, orgName, space);
			}

			if (!StringUtil.isEmpty(spaceGuid)) {
				// apps
				String listAppUrl = host + "/v2/spaces/" + spaceGuid + "/apps?inline-relations-depth=1";
				HttpGet httpGetApps = new HttpGet(listAppUrl);
				CloudFoundryClientUtil.setAccessHeaders(httpGetApps, session);
				// services
				String listAllServiceUrl = host + "/v2/spaces/" + spaceGuid
						+ "/service_instances?inline-relations-depth=1&return_user_provided_service_instances=true";
				HttpGet httpGetService = new HttpGet(listAllServiceUrl);
				CloudFoundryClientUtil.setAccessHeaders(httpGetService, session);

				try {
					// ************************* application informations
					// ***********************
					Future<Map<String, Object>> resourcesRes = executor.submit(new ResourceCall(httpClient, httpGetApps,
							ResourceCall.HTTP, ((URL) session.getAttribute(LoginHandler.TARGET)).toString(),
							token.getTokenType() + " " + token.getToken(session)));
					if (resourcesRes != null) {
						List<Map<String, Object>> resources = (List<Map<String, Object>>) resourcesRes.get()
								.get("list");
						String[] memoryKeys = { "entity", "memory" };
						for (Map<String, Object> appRes : resources) {
							memoryUsed += (int) ((Map<String, Object>) appRes.get(memoryKeys[0])).get(memoryKeys[1]);
						}
					}

					// ************************* services informations
					// ***********************
					Future<Map<String, Object>> serviceFu = executor.submit(new ResourceCall(httpClient, httpGetService,
							ResourceCall.HTTP, ((URL) session.getAttribute(LoginHandler.TARGET)).toString(),
							token.getTokenType() + " " + token.getToken(session)));
					if (serviceFu != null) {
						serviceNum += (Integer) serviceFu.get().get("resource_size");
					}
				} catch (Exception e) {
					throw e;
				} finally {
					if (httpGetService != null) {
						httpGetService.abort();
					}
					if (httpGetApps != null) {
						httpGetApps.abort();
					}
				}

			}
		}
		// 将应用的状态信息放入map中
		resMap.put("serviceNum", serviceNum);
		resMap.put("memoryUsed", memoryUsed);
		Map<String, Object> orgDetail = OrgApi.getParticularOrg(orgName, session);
		if (orgDetail != null) {
			// quotas
			String quotaUrl = host
					+ (String) ((Map<String, Object>) orgDetail.get("entity")).get("quota_definition_url");
			HttpGet httpGetQuota = new HttpGet(quotaUrl);
			CloudFoundryClientUtil.setAccessHeaders(httpGetQuota, session);
			try {

				// ************************* quota informations
				// ***********************
				Future<Map<String, Object>> quotaFu = executor.submit(new ResourceCall(httpClient, httpGetQuota,
						ResourceCall.GETITEM, ((URL) session.getAttribute(LoginHandler.TARGET)).toString(),
						token.getTokenType() + " " + token.getToken(session)));
				if (quotaFu != null) {
					Map<String, Object> data = (Map<String, Object>) quotaFu.get().get("entity");
					resMap.put("memoryAll", data.get("memory_limit"));
					resMap.put("serviceAll", data.get("total_services"));
				}
			} catch (Exception e) {
				throw e;
			} finally {
				if (httpGetQuota != null) {
					httpGetQuota.abort();
				}
				if (httpClient != null) {
					httpClient.getConnectionManager().shutdown();
				}

			}
		}
	}

	/**
	 * 通过orgName得到basicinfo
	 * 
	 * @param session
	 * @param orgName
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static Map<String, Object> getBasicInfoByOrgName(HttpSession session, String orgName) throws Exception {
		Map<String, Object> mapRes = new HashMap<String, Object>();

		ThreadPoolExecutor executor = MutiThreadUtil.getExecutorService();

		HttpClient httpClient = new DefaultHttpClient();
		OauthToken token = (OauthToken) session.getAttribute(LoginHandler.TOKEN);
		String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
		// 得到所属orgName的所有spaces
		List<Map<String, Object>> list = SpaceApi.list_spaces_by_org(session, orgName);

		int updating = 0;
		int started = 0;
		int stopped = 0;
		int memoryUsed = 0;
		int applicationNum = 0;
		int serviceNum = 0;
		int routesNum = 0;
		// 遍历spaces
		for (Map<String, Object> map : list) {
			// 得到space的名字
			String space = (String) map.get("name");
			String spaceGuid = null;
			// 得到space的Guid
			if (!StringUtil.isEmpty(orgName) && !StringUtil.isEmpty(space)) {
				spaceGuid = UserApi.get_space_id(session, orgName, space);
			}

			if (!StringUtil.isEmpty(spaceGuid)) {
				// apps
				String listAppUrl = host + "/v2/spaces/" + spaceGuid + "/apps?inline-relations-depth=1";
				HttpGet httpGetApps = new HttpGet(listAppUrl);
				CloudFoundryClientUtil.setAccessHeaders(httpGetApps, session);
				// routes
				String routeUrl = host + "/v2/spaces/" + spaceGuid + "/routes?inline-relations-depth=1";
				HttpGet httpGetRoute = new HttpGet(routeUrl);
				CloudFoundryClientUtil.setAccessHeaders(httpGetRoute, session);

				// services
				String listAllServiceUrl = host + "/v2/spaces/" + spaceGuid
						+ "/service_instances?inline-relations-depth=1&return_user_provided_service_instances=true";
				HttpGet httpGetService = new HttpGet(listAllServiceUrl);
				CloudFoundryClientUtil.setAccessHeaders(httpGetService, session);

				try {
					// ************************* application informations
					// ***********************
					Future<Map<String, Object>> resourcesRes = executor.submit(new ResourceCall(httpClient, httpGetApps,
							ResourceCall.HTTP, ((URL) session.getAttribute(LoginHandler.TARGET)).toString(),
							token.getTokenType() + " " + token.getToken(session)));
					if (resourcesRes != null) {
						List<Map<String, Object>> resources = (List<Map<String, Object>>) resourcesRes.get()
								.get("list");
						applicationNum += resources.size();

						String[] stateKeys = { "entity", "state" };
						String[] memoryKeys = { "entity", "memory" };
						for (Map<String, Object> appRes : resources) {
							String state = (String) ((Map<String, Object>) appRes.get(stateKeys[0])).get(stateKeys[1]);
							if ("UPDATING".equals(state)) {
								updating++;
							} else if ("STARTED".equals(state)) {
								started++;
							} else {
								stopped++;
							}

							memoryUsed += (int) ((Map<String, Object>) appRes.get(memoryKeys[0])).get(memoryKeys[1]);
						}
						// ************************* services informations
						// ***********************
						Future<Map<String, Object>> serviceFu = executor
								.submit(new ResourceCall(httpClient, httpGetService, ResourceCall.HTTP,
										((URL) session.getAttribute(LoginHandler.TARGET)).toString(),
										token.getTokenType() + " " + token.getToken(session)));
						if (serviceFu != null) {
							serviceNum += (Integer) serviceFu.get().get("resource_size");
						}
						// ************************* route routesNum
						// *************************
						Future<Map<String, Object>> routeFu = executor.submit(new ResourceCall(httpClient, httpGetRoute,
								ResourceCall.HTTP, ((URL) session.getAttribute(LoginHandler.TARGET)).toString(),
								token.getTokenType() + " " + token.getToken(session)));
						if (routeFu != null) {
							routesNum += (Integer) routeFu.get().get("resource_size");
						}
					}
				} catch (Exception e) {
					throw e;
				} finally {
					if (httpGetRoute != null) {
						httpGetRoute.abort();
					}
					if (httpGetService != null) {
						httpGetService.abort();
					}
					if (httpGetApps != null) {
						httpGetApps.abort();
					}
				}

			}
		}
		// 将应用的状态信息放入map中
		mapRes.put("updating", updating);
		mapRes.put("started", started);
		mapRes.put("stopped", stopped);
		mapRes.put("memoryUsed", memoryUsed);
		// 将应用的数量放入map中
		mapRes.put("applicationNum", applicationNum);
		mapRes.put("serviceNum", serviceNum);
		mapRes.put("routesNum", routesNum);
		Map<String, Object> orgDetail = OrgApi.getParticularOrg(orgName, session);
		if (orgDetail != null) {
			// quotas
			String quotaUrl = host
					+ (String) ((Map<String, Object>) orgDetail.get("entity")).get("quota_definition_url");
			HttpGet httpGetQuota = new HttpGet(quotaUrl);
			CloudFoundryClientUtil.setAccessHeaders(httpGetQuota, session);
			try {

				// ************************* quota informations
				// ***********************
				Future<Map<String, Object>> quotaFu = executor.submit(new ResourceCall(httpClient, httpGetQuota,
						ResourceCall.GETITEM, ((URL) session.getAttribute(LoginHandler.TARGET)).toString(),
						token.getTokenType() + " " + token.getToken(session)));
				if (quotaFu != null) {
					Map<String, Object> data = (Map<String, Object>) quotaFu.get().get("entity");
					mapRes.put("memoryAll", data.get("memory_limit"));
					mapRes.put("routesAll", data.get("total_routes"));
					mapRes.put("serviceAll", data.get("total_services"));
				}
			} catch (Exception e) {
				throw e;
			} finally {
				if (httpGetQuota != null) {
					httpGetQuota.abort();
				}

				if (httpClient != null) {
					httpClient.getConnectionManager().shutdown();
				}

			}
		}
		return mapRes;
	}

	/**
	 * 获取首页统计信息
	 * 
	 * @param session
	 * @param mapper
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static Map<String, Object> getBasicInfo(HttpSession session) throws Exception {

		Map<String, Object> mapRes = new HashMap<String, Object>();

		ThreadPoolExecutor executor = MutiThreadUtil.getExecutorService();

		HttpClient httpClient = new DefaultHttpClient();
		OauthToken token = (OauthToken) session.getAttribute(LoginHandler.TOKEN);
		String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
		// apps
		String listAppUrl = host + "/v2/apps?inline-relations-depth=1";
		HttpGet httpGetApps = new HttpGet(listAppUrl);
		CloudFoundryClientUtil.setAccessHeaders(httpGetApps, session);
		// routes
		String routeUrl = host + "/v2/routes?inline-relations-depth=1";
		HttpGet httpGetRoute = new HttpGet(routeUrl);
		CloudFoundryClientUtil.setAccessHeaders(httpGetRoute, session);

		// services
		String listAllServiceUrl = host + "/v2/service_instances?inline-relations-depth=1";
		HttpGet httpGetService = new HttpGet(listAllServiceUrl);
		CloudFoundryClientUtil.setAccessHeaders(httpGetService, session);
		try {
			// ************************* application informations
			// ***********************
			Future<Map<String, Object>> resourcesRes = executor.submit(new ResourceCall(httpClient, httpGetApps,
					ResourceCall.HTTP, ((URL) session.getAttribute(LoginHandler.TARGET)).toString(),
					token.getTokenType() + " " + token.getToken(session)));
			if (resourcesRes != null) {
				List<Map<String, Object>> resources = (List<Map<String, Object>>) resourcesRes.get().get("list");
				mapRes.put("applicationNum", resources.size());

				String[] stateKeys = { "entity", "state" };
				String[] memoryKeys = { "entity", "memory" };
				int updating = 0;
				int started = 0;
				int stopped = 0;
				int memoryUsed = 0;
				for (Map<String, Object> appRes : resources) {
					String state = (String) ((Map<String, Object>) appRes.get(stateKeys[0])).get(stateKeys[1]);
					if ("UPDATING".equals(state)) {
						updating++;
					} else if ("STARTED".equals(state)) {
						started++;
					} else {
						stopped++;
					}

					memoryUsed += (int) ((Map<String, Object>) appRes.get(memoryKeys[0])).get(memoryKeys[1]);
				}
				mapRes.put("updating", updating);
				mapRes.put("started", started);
				mapRes.put("stopped", stopped);
				mapRes.put("memoryUsed", memoryUsed);

				// ************************* user informations
				// ***********************
				mapRes.put("orgnization", LoginHandler.ORG);
				mapRes.put("space", LoginHandler.SPACE);

				// ************************* services informations
				// ***********************
				Future<Map<String, Object>> serviceFu = executor.submit(new ResourceCall(httpClient, httpGetService,
						ResourceCall.HTTP, ((URL) session.getAttribute(LoginHandler.TARGET)).toString(),
						token.getTokenType() + " " + token.getToken(session)));
				if (serviceFu != null) {
					mapRes.put("serviceNum", serviceFu.get().get("resource_size"));
				}
				// ************************* route routesNum
				// *************************
				Future<Map<String, Object>> routeFu = executor.submit(new ResourceCall(httpClient, httpGetRoute,
						ResourceCall.HTTP, ((URL) session.getAttribute(LoginHandler.TARGET)).toString(),
						token.getTokenType() + " " + token.getToken(session)));
				if (routeFu != null) {
					mapRes.put("routesNum", routeFu.get().get("resource_size"));
				}
			}
		} catch (Exception e) {
			throw e;
		} finally {
			if (httpGetRoute != null) {
				httpGetRoute.abort();
			}
			if (httpGetService != null) {
				httpGetService.abort();
			}
			if (httpGetApps != null) {
				httpGetApps.abort();
			}
		}

		List<Map<String, Object>> orgs = OrgApi.list_orgs(session);
		HttpGet httpGetQuota = null;
		int memoryAll = 0;
		int routesAll = 0;
		int serviceAll = 0;

		try {
			for (Map<String, Object> map : orgs) {
				String org = (String) map.get("name");
				Map<String, Object> orgDetail = OrgApi.getParticularOrg(org, session);
				if (orgDetail != null) {
					// quotas
					String quotaUrl = host
							+ (String) ((Map<String, Object>) orgDetail.get("entity")).get("quota_definition_url");
					httpGetQuota = new HttpGet(quotaUrl);
					CloudFoundryClientUtil.setAccessHeaders(httpGetQuota, session);

					// ************************* quota informations
					// ***********************
					Future<Map<String, Object>> quotaFu = executor.submit(new ResourceCall(httpClient, httpGetQuota,
							ResourceCall.GETITEM, ((URL) session.getAttribute(LoginHandler.TARGET)).toString(),
							token.getTokenType() + " " + token.getToken(session)));

					if (quotaFu != null) {
						Map<String, Object> data = (Map<String, Object>) quotaFu.get().get("entity");
						memoryAll += (int) data.get("memory_limit");
						routesAll += (int) data.get("total_routes");
						serviceAll += (int) data.get("total_services");
					}
				}
			}
			mapRes.put("memoryAll", memoryAll);
			mapRes.put("routesAll", routesAll);
			mapRes.put("serviceAll", serviceAll);
		} catch (Exception e) {
			throw e;
		} finally {
			if (httpGetQuota != null) {
				httpGetQuota.abort();
			}

			if (httpClient != null) {
				httpClient.getConnectionManager().shutdown();
			}

		}
		return mapRes;
	}

}
